import React, { useRef, useEffect, useState, useCallback, forwardRef, useImperativeHandle } from 'react'
import { ViewportState, SceneBlockData, DragState, ZoomLevel } from './types'
import { TimelineRenderer } from './TimelineRenderer'
import { TimelineLayoutCalculator } from './TimelineLayoutCalculator'
import { TimelineInteractionHandler } from './TimelineInteractionHandler'
import { ZoomController } from './ZoomController'
import { StoryboardScene } from '../../../types/document'

export interface TimelineCanvasProps {
  scenes: StoryboardScene[]
  selectedSceneId: string | null
  onSceneSelect: (sceneId: string | null) => void
  onSceneReorder: (fromIndex: number, toIndex: number) => void
  className?: string
  style?: React.CSSProperties
}

export interface TimelineCanvasRef {
  zoomIn: () => void
  zoomOut: () => void
  zoomToFit: () => void
  scrollToScene: (sceneId: string) => void
}

/**
 * 时间线Canvas组件
 * 负责渲染时间轴和处理交互
 */
export const TimelineCanvas = forwardRef<TimelineCanvasRef, TimelineCanvasProps>(({
  scenes,
  selectedSceneId,
  onSceneSelect,
  onSceneReorder,
  className,
  style
}, ref) => {
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const containerRef = useRef<HTMLDivElement>(null)
  
  // 渲染器和控制器实例
  const rendererRef = useRef<TimelineRenderer>()
  const layoutCalculatorRef = useRef<TimelineLayoutCalculator>()
  const interactionHandlerRef = useRef<TimelineInteractionHandler>()
  const zoomControllerRef = useRef<ZoomController>()
  
  // 状态
  const [viewport, setViewport] = useState<ViewportState>({
    scale: 10.0,
    offsetX: 0,
    width: 800,
    height: 120,
    totalDuration: 0
  })
  
  const [dragState, setDragState] = useState<DragState>({
    isDragging: false,
    draggedSceneId: null,
    dragStartX: 0,
    dragCurrentX: 0,
    insertIndex: -1,
    originalIndex: -1
  })
  
  const [sceneBlocks, setSceneBlocks] = useState<SceneBlockData[]>([])
  const [timeMarks, setTimeMarks] = useState<Array<{x: number; time: number; label: string; isPrimary: boolean}>>([])
  
  // 计算总时长
  const totalDuration = scenes.reduce((total, scene) => {
    return total + (scene.timing?.duration || scene.duration || 5)
  }, 0)
  
  // 初始化组件
  useEffect(() => {
    if (!canvasRef.current || !containerRef.current) return
    
    // 创建渲染器和控制器
    rendererRef.current = new TimelineRenderer(canvasRef.current)
    layoutCalculatorRef.current = new TimelineLayoutCalculator()
    
    // 创建缩放控制器
    zoomControllerRef.current = new ZoomController(
      viewport,
      setViewport
    )
    
    // 创建交互处理器
    interactionHandlerRef.current = new TimelineInteractionHandler(
      layoutCalculatorRef.current,
      onSceneSelect,
      onSceneReorder,
      setDragState
    )
    
    // 设置初始视口尺寸
    updateCanvasSize()
    
    // 添加窗口大小监听器
    const handleResize = () => updateCanvasSize()
    window.addEventListener('resize', handleResize)
    
    return () => {
      window.removeEventListener('resize', handleResize)
      interactionHandlerRef.current?.cleanup()
    }
  }, [onSceneSelect, onSceneReorder])
  
  // 更新Canvas尺寸
  const updateCanvasSize = useCallback(() => {
    if (!containerRef.current || !rendererRef.current || !zoomControllerRef.current) return
    
    const rect = containerRef.current.getBoundingClientRect()
    const newWidth = rect.width
    const newHeight = 120
    
    rendererRef.current.updateSize()
    zoomControllerRef.current.updateViewportSize(newWidth, newHeight)
  }, [])
  
  // 更新视口状态
  useEffect(() => {
    setViewport(prev => ({
      ...prev,
      totalDuration
    }))
  }, [totalDuration])
  
  // 计算场景块和时间刻度
  useEffect(() => {
    if (!layoutCalculatorRef.current) return
    
    const newSceneBlocks = layoutCalculatorRef.current.calculateSceneBlocks(scenes, viewport)
    const newTimeMarks = layoutCalculatorRef.current.calculateTimeMarks(viewport)
    
    setSceneBlocks(newSceneBlocks)
    setTimeMarks(newTimeMarks)
    
    // 更新交互处理器状态
    interactionHandlerRef.current?.updateState(viewport, newSceneBlocks)
  }, [scenes, viewport])
  
  // 渲染Canvas
  useEffect(() => {
    if (!rendererRef.current) return
    
    rendererRef.current.render(
      viewport,
      sceneBlocks,
      timeMarks,
      dragState,
      selectedSceneId
    )
  }, [viewport, sceneBlocks, timeMarks, dragState, selectedSceneId])
  
  // 鼠标事件处理
  const handleMouseDown = useCallback((event: React.MouseEvent) => {
    interactionHandlerRef.current?.handleMouseDown(event.nativeEvent)
  }, [])
  
  const handleMouseMove = useCallback((event: React.MouseEvent) => {
    interactionHandlerRef.current?.handleMouseMove(event.nativeEvent)
  }, [])
  
  const handleMouseUp = useCallback((event: React.MouseEvent) => {
    interactionHandlerRef.current?.handleMouseUp(event.nativeEvent)
  }, [])
  
  const handleMouseLeave = useCallback(() => {
    interactionHandlerRef.current?.handleMouseLeave()
  }, [])
  
  const handleWheel = useCallback((event: React.WheelEvent) => {
    const rect = canvasRef.current?.getBoundingClientRect()
    if (!rect || !zoomControllerRef.current) return
    
    const mouseX = event.clientX - rect.left
    zoomControllerRef.current.handleWheel(event.nativeEvent, mouseX)
  }, [])
  
  // 暴露控制方法
  const zoomIn = useCallback(() => {
    zoomControllerRef.current?.zoomIn()
  }, [])
  
  const zoomOut = useCallback(() => {
    zoomControllerRef.current?.zoomOut()
  }, [])
  
  const zoomToFit = useCallback(() => {
    zoomControllerRef.current?.zoomToFit(totalDuration)
  }, [totalDuration])
  
  const scrollToScene = useCallback((sceneId: string) => {
    const scene = scenes.find(s => s.id === sceneId)
    if (!scene || !zoomControllerRef.current) return
    
    // 计算场景开始时间
    let startTime = 0
    for (const s of scenes) {
      if (s.id === sceneId) break
      startTime += s.timing?.duration || s.duration || 5
    }
    
    zoomControllerRef.current.scrollToTime(startTime)
  }, [scenes])
  
  // 暴露给父组件的方法
  useImperativeHandle(ref, () => ({
    zoomIn,
    zoomOut,
    zoomToFit,
    scrollToScene
  }))
  
  return (
    <div 
      ref={containerRef}
      className={`timeline-canvas-container ${className || ''}`}
      style={{
        width: '100%',
        height: '120px',
        position: 'relative',
        border: '1px solid #e8e8e8',
        borderRadius: '4px',
        overflow: 'hidden',
        backgroundColor: '#fafafa',
        ...style
      }}
    >
      <canvas
        ref={canvasRef}
        style={{
          display: 'block',
          width: '100%',
          height: '100%',
          cursor: dragState.isDragging ? 'grabbing' : 'default'
        }}
        onMouseDown={handleMouseDown}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        onMouseLeave={handleMouseLeave}
        onWheel={handleWheel}
      />
    </div>
  )
})